package com.example.taluo.logic;

import com.example.taluo.entity.dto.gamedto.GameState;
import com.example.taluo.entity.dto.gamedto.Message;
import com.example.taluo.entity.dto.gamedto.PlayerState;
import com.example.taluo.enums.MessageType;
import com.example.taluo.utils.JsonUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.codehaus.jackson.map.ObjectMapper;

import java.util.Map;
import java.util.Set;
import java.util.UUID;

/*** @Author supersaiya
 * @Description  游戏逻辑处理

 * @Date 2025/2/18 17:01

 * @Version 1.0*/
// 游戏服务器处理器（WebSocket 消息处理）
public class GameServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        String content = msg.text();
        System.out.println("Received game server message: " + content); // 打印接收到的 WebSocket 消息

        Map<String, Object> message = JsonUtil.fromJson(content, Map.class); // 将消息内容解析为 Map 对象
        String type = (String) message.get("type"); // 获取消息类型

        switch (type) {
            case "CREATE_ROOM": // 处理创建房间请求
                handleCreateRoom(ctx, message);
                break;
            case "JOIN_ROOM": // 处理加入房间请求
                handleJoinRoom(ctx, message);
                break;
            case "PLAY_CARD": // 处理出牌请求
                handlePlayCard(ctx, message);
                break;
            case "END_TURN": // 处理回合结束请求
                handleEndTurn(ctx, message);
                break;
            default: // 处理未知消息类型
                ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(Map.of(
                        "type", "ERROR",
                        "reason", "Unknown message type."
                )))); // 返回错误消息
        }
    }

    // 处理创建房间请求
    private void handleCreateRoom(ChannelHandlerContext ctx, Map<String, Object> message) {
        String roomId = UUID.randomUUID().toString(); // 生成唯一房间 ID
        GameRoom room = new GameRoom(roomId); // 创建新房间
        GameRoomManager.addGameRoom(roomId, room); // 将房间添加到全局房间管理器

        room.addPlayer(ctx.channel().id().asLongText(), ctx.channel()); // 将当前玩家加入房间

        // 向玩家发送房间创建成功的消息
        ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(Map.of(
                "type", "CREATE_ROOM_SUCCESS",
                "roomId", roomId
        ))));
    }

    // 处理加入房间请求
    private void handleJoinRoom(ChannelHandlerContext ctx, Map<String, Object> message) {
        String roomId = (String) message.get("roomId"); // 获取房间 ID

        // 从全局房间管理器中获取房间
        GameRoom room = GameRoomManager.getGameRoom(roomId);
        if (room != null) {
            room.addPlayer(ctx.channel().id().asLongText(), ctx.channel()); // 将玩家加入房间

            // 向玩家发送加入房间成功的消息
            ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(Map.of(
                    "type", "JOIN_ROOM_SUCCESS",
                    "roomId", roomId
            ))));

            // 如果房间有两位玩家，启动游戏
            if (room.getPlayers().size() == 2) {
                room.startGame();
            }
        } else {
            // 如果房间不存在，返回错误消息
            ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(Map.of(
                    "type", "ERROR",
                    "reason", "Room not found."
            ))));
        }
    }

    // 处理出牌请求
    private void handlePlayCard(ChannelHandlerContext ctx, Map<String, Object> message) {
        String roomId = (String) message.get("roomId");
        int cardId = (Integer) message.get("cardId");

        GameRoom room = GameRoomManager.getGameRoom(roomId);
        if (room != null) {
            String playerId = ctx.channel().id().asLongText();
            GameState gameState = room.getGameState();
            GameLogic gameLogic = room.getGameLogic();

            // 获取当前玩家和对手
            PlayerState currentPlayer = gameState.getPlayer(playerId);
            if (currentPlayer == null) {
                ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(Map.of(
                        "type", "ERROR",
                        "reason", "Player not found in game."
                ))));
                return;
            }

            // 检查是否是当前玩家的回合
            if (!gameState.getCurrentPlayerId().equals(playerId)) {
                ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(Map.of(
                        "type", "ERROR",
                        "reason", "Not your turn to play."
                ))));
                return;
            }

            // 使用卡牌并自动切换回合
            gameLogic.useCard(gameState, cardId);

            // 广播游戏状态
            room.broadcastGameState();
        }
    }

    // 处理回合结束请求
    private void handleEndTurn(ChannelHandlerContext ctx, Map<String, Object> message) {
        String roomId = (String) message.get("roomId"); // 获取房间 ID

        // 从全局房间管理器中获取房间
        GameRoom room = GameRoomManager.getGameRoom(roomId);
        if (room != null) {
            // 切换回合并更新游戏状态
            room.broadcastGameState(); // 向房间内所有玩家广播游戏状态
        }
    }

    // 获取房间内对手的 ID
    private String getOpponentId(GameRoom room, String currentId) {
        Set<String> playerIds = room.getPlayers().keySet(); // 获取房间内所有玩家的 ID
        for (String id : playerIds) {
            if (!id.equals(currentId)) { // 找到对手的 ID 并返回
                return id;
            }
        }
        return null; // 如果没有对手，返回 null
    }
}